//C19:ep_19_4.cpp 
// Listing 19.4 -- Using Operator ostream
#include <fstream>
#include <iostream>
#include <ostream>
using namespace std;

const int DefaultSize = 10;

class Animal
{
    public:
        Animal(int);
        Animal();
        ~Animal() {}
        int GetWeight() const {return itsWeight; }
        void Display() const { cout << itsWeight; }
    private:
        int itsWeight;        
};

Animal::Animal(int weight)
: itsWeight(weight) {}


template<class T>
class Array
{
    public:
        Array(int itsSize = DefaultSize);
        Array(const Array &rhs);
        ~Array() {delete [] pType; }

        Array& operator=(const Array&);
        T& operator[](int offSet)
        {
            return pType[offSet];
        }

        const T& operator[](int offSet) const
        {
            return pType[offSet];
        }

        int GetSize() const { return itsSize; }
        // template<class T>
        friend ofstream& operator<<(ostream&, Array<T>&);
    private:
        T *pType;
        int itsSize;    
};

template<class T>
ostream& operator<<(ostream& output, Array<T>& theArray)
{
    for (int i = 0; i < theArray.itsSize; i++)
    {
        output << "[" << i << "] " << theArray[i] << endl;
    }
    return output;
}

//implementations follow...
template<class T>
Array<T>::Array(int size)
: itsSize(size) 
{
    pType = new T[size];
    for (int i = 0; i < size; i++)
    {
        pType[i] = 0;
    }
}

template<class T>
Array<T>::Array(const Array &rhs)
{
    itsSize = rhs.GetSize();
    pType = new T[itsSize];
    for (int i = 0; i < itsSize; i++)
    {
        pType[i] = rhs[i];
    }
}

template<class T>
Array<T>& Array<T>::operator=(const Array<T> &rhs)
{
    if(this == &rhs)
    {
        return *this;
    }

    delete [] pType;
    itsSize = rhs.GetSize();
    pType = new T[itsSize];
    for (int i = 0; i < itsSize; i++)
    {
        pType[i] = rhs[i];
    }
    return *this;
}

int main(void)
{
    bool Stop = false;
    int offset, value;
    Array<int> theArray;

    while (Stop == false)
    {
        cout << "Enter an offset (0-9) ";
        cout << "and a value, (-1 to stop): ";
        cin >> offset >> value;

        if(offset < 0)
        {
            break;
        }

        if(offset > 9)
        {
            cout << "***Please use values  between 0 and 9.***\n";
            continue;
        }

        theArray[offset] = value;
    }

    cout << "\nHere's the entire array:\n";
    cout << theArray << endl;
}
